import 'package:flutter/material.dart';
import 'package:flutter_application/app/app_color.dart';

class ListPage extends StatefulWidget {
  const ListPage({Key? key}) : super(key: key);

  @override
  State<ListPage> createState() => _ListPageState();
}

class _ListPageState extends State<ListPage> {
  late ScrollController controller;

  late List<Map<String, dynamic>> tabValues;

  @override
  void initState() {
    super.initState();

    tabValues = [
      {'title': '基本使用', 'view': createList()},
      {'title': '嵌套问题', 'view': createGridAndList()},
      {'title': '嵌套解决', 'view': createSliverList()}
    ];
  }

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
        length: _tabs().length,
        child: Scaffold(
            appBar: AppBar(
              title: const Text('ListView相关'),
              bottom: TabBar(
                tabs: _tabs(),
              ),
            ),
            body: SafeArea(
                child: TabBarView(
              children: _tabViews(),
            ))));
  }

  _tabs() {
    return tabValues.map((value) {
      return Tab(
        text: value['title'],
      );
    }).toList();
  }

  _tabViews() {
    return tabValues.map((value) {
      return value['view'] as Widget;
    }).toList();
  }

  //TODO:ListView常用方式
  Widget createList() {
    controller = ScrollController()
      ..addListener(() {
        debugPrint('颜色滑动监听回调 =》${controller.offset}');
      });

    return Column(
      children: [
        const Text('1、数据较少时，可以直接使用'),
        SizedBox(
          height: 120,
          child: ListView(
            children: [itemView(), itemView(), itemView()],
          ),
        ),
        const Text('2、动态创建列表，性能更好'),
        Expanded(
            flex: 1,
            child: ListView.builder(
              itemBuilder: (BuildContext context, int index) {
                return itemView(index: index);
              },
              // physics: const NeverScrollableScrollPhysics(), //不可滚动
              itemExtent: 50, //行高
              itemCount: 50, //行数
            )),
        const Text('3、带风格线'),
        Expanded(
            flex: 1,
            child: ListView.separated(
              itemBuilder: (BuildContext context, int index) {
                return itemView(index: index, color: Colors.transparent);
              },
              separatorBuilder: (BuildContext context, int index) =>
                  const Divider(),
              controller: controller,
              itemCount: 50, //行数
            ))
      ],
    );
  }

  //TODO:相互嵌套场景
  //GridView + ListView\n滚动的时候无法作为一个整体
  Widget createGridAndList() {
    return SingleChildScrollView(
      child: Container(
        color: Colors.green,
        child: Column(children: [
          const Text(
            'GridView + ListView\n滚动的时候无法做为一个整体',
            textAlign: TextAlign.center,
          ),
          SizedBox(
            height: 100 * 2,
            child: GridView.count(
              crossAxisCount: 4,
              children: List.generate(8, (index) {
                return Container(
                  color: Colors.primaries[index % Colors.primaries.length],
                  alignment: Alignment.center,
                  child: Text(
                    '$index',
                    style: const TextStyle(color: Colors.white, fontSize: 20),
                  ),
                );
              }).toList(),
            ),
          ),
          SizedBox(
              height: 300,
              child: ListView.builder(
                itemBuilder: (BuildContext context, int index) {
                  return itemView(index: index);
                },
                itemExtent: 50, //行高
                itemCount: 50, //行数
              )),
          Container(
            height: 500,
            color: AppColor.randomColor(),
          )
        ]),
      ),
    );
  }

  //TODO:Sliver滚动的时候作为一个整体
  Widget createSliverList() {
    return CustomScrollView(
      slivers: <Widget>[
        SliverGrid(
          gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
            maxCrossAxisExtent: 100.0, //最大宽度
            mainAxisSpacing: 10.0, //主轴间隔
            crossAxisSpacing: 10.0, //纵轴间隔
            childAspectRatio: 1.0, //长宽比例
          ),
          delegate: SliverChildBuilderDelegate(
            (BuildContext context, int index) {
              return Container(
                color: Colors.primaries[index % Colors.primaries.length],
                alignment: Alignment.center,
                child: Text(
                  '$index',
                  style: const TextStyle(color: Colors.white, fontSize: 20),
                ),
              );
            },
            childCount: 8,
          ),
        ),

        //非Sliver组件需要SliverToBoxAdapter适配
        const SliverToBoxAdapter(
          child: Text(
              '【SliverFixedExtentList】和SliverList用法一样，唯一的区别就是SliverFixedExtentList是固定子控件的高度的，SliverFixedExtentList比SliverList更加高效，因为SliverFixedExtentList无需计算子控件的布局。'),
        ),

        SliverFixedExtentList(
          itemExtent: 50.0,
          delegate: SliverChildBuilderDelegate(
            (BuildContext context, int index) {
              return itemView(index: index);
            },
            childCount: 5,
          ),
        ),

        //非Sliver组件需要SliverToBoxAdapter适配
        const SliverToBoxAdapter(
          child: Text(
              '【SliverPrototypeExtentList】比SliverFixedExtentList更加灵活，因为SliverPrototypeExtentList不必指定像素高度。SliverPrototypeExtentList通常用于不确定item高度，随prototypeItem变化的场景,比如调整整个App字体的大小，字体越大，需要的高度越高，如果使用SliverFixedExtentList指定具体的高度，会出现字体显示不全的状况。'),
        ),

        SliverPrototypeExtentList(
          //控制元素高度
          prototypeItem: const SizedBox(
            height: 20,
          ),
          delegate: SliverChildBuilderDelegate((content, index) {
            return itemView(index: index);
          }, childCount: 10),
        ),
      ],
    );
  }

  itemView({int? index, Color? color}) {
    return Container(
      alignment: AlignmentDirectional.center,
      color: color ?? AppColor.randomColor(),
      height: 50,
      child: Text(index != null ? index.toString() : ''),
    );
  }
}
